package com.dk.assertion;

import com.alibaba.fastjson.JSON;
import com.dk.domain.ApiAutoTestEntity;
import com.dk.domain.assertion.CheckPointEntity;
import com.dk.domain.assertion.DbCheckEntity;
import com.dk.domain.assertion.ResCheckEntity;
import com.dk.enumerate.DkRuleEnum;
import com.dk.exception.ExcelDataException;
import com.dk.testcase.BaseCase;
import com.dk.util.config.ReadConfig;
import com.dk.util.http.res.ResUtil;
import com.dk.util.jdbc.JdbcUtil;
import com.dk.util.log.Log;

import java.sql.Connection;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * 包含断言实现类
 */
public class ContainLink extends AssertChain {

    /**
     * 包含链实现
     * @param apiAutoTestEntity 用例对象
     * @return
     */
    @Override
    public ApiAutoTestEntity assertBody(ApiAutoTestEntity apiAutoTestEntity) {
        //最终返回结果
        AtomicBoolean result = new AtomicBoolean(true);
        //获取检查点对象
        CheckPointEntity checkPointEntity = JSON.parseObject(apiAutoTestEntity.getCheckPoint(),CheckPointEntity.class);
        //获取响应校验集合
        List<ResCheckEntity> resCheckList = checkPointEntity.getResCheck();
        //获取数据库校验集合
        List<DbCheckEntity> dbCheckList = checkPointEntity.getDbCheck();

        //当响应校验集合不为空时，遍历集合筛选出
        if(resCheckList!=null&&resCheckList.size()!=0){
            resCheckList.stream().filter(resCheckEntity -> resCheckEntity.getCheckType().equals(DkRuleEnum.ASSERT_TYPE_CONTAIN.getValue())).forEach(resCheckEntity->{
                if(resCheckEntity.getCheckMain().toUpperCase().equals(DkRuleEnum.HEADER.getValue())){
                    Log.info("---【用例断言】:开始执行响应头包含断言");
                    result.set(AssertUtil.assertContain(apiAutoTestEntity.getResHeaders(), resCheckEntity.getTargetResult()));
                    Log.info("---【用例断言】:响应头包含断言断言成功");
                }else if(resCheckEntity.getCheckMain().toUpperCase().equals(DkRuleEnum.BODY.getValue())){
                    Log.info("---【用例断言】:开始执行响应体包含断言");
                    result.set(AssertUtil.assertContain(apiAutoTestEntity.getResBody(), resCheckEntity.getTargetResult()));
                    Log.info("---【用例断言】:响应体包含断言断言成功");
                }else{
                    try {
                        throw new ExcelDataException("---【error】:checkPoint字段的resCheck的CheckMain不存在:请检查测试数据,CaseNum:"+apiAutoTestEntity.getCaseNum()+";");
                    } catch (ExcelDataException e) {
                        e.printStackTrace();
                    }
                }

            });
        }

        //当数据库校验集合不为空时，遍历集合进行断言
        if(dbCheckList!=null&&dbCheckList.size()!=0){
            dbCheckList.stream().filter(dbCheckEntity -> dbCheckEntity.getCheckType().equals(DkRuleEnum.ASSERT_TYPE_CONTAIN.getValue())).forEach(dbCheckEntity->{
                Map<String,String> dbConfig = BaseCase.dbConfigMap.get(dbCheckEntity.getCheckDb());
                Connection conn = JdbcUtil.getConnection(ReadConfig.JDBC_DRIVER,
                        dbConfig.get(DkRuleEnum.DB_URL.getValue()),
                        dbConfig.get(DkRuleEnum.DB_USER.getValue()),
                        dbConfig.get(DkRuleEnum.DB_PWD.getValue()));
                //获取sql查询结果
                List<Map<String,String>> resultList = JdbcUtil.select(conn,dbCheckEntity.getCheckSql());
                if(Integer.valueOf(dbCheckEntity.getCheckSub())<resultList.size()){
                    //从查询结果获取需要操作的对象
                    Map<String,String> handle = resultList.get(Integer.valueOf(dbCheckEntity.getCheckSub()));
                    Log.info("---【用例断言】:查询结果:"+handle+";需要比较的对象下标:"+dbCheckEntity.getCheckSub()+";断言字段:"+dbCheckEntity.getCheckFiele()+";");
                    Log.info("---【用例断言】:开始执行数据库数据包含断言");
                    result.set(AssertUtil.assertContain(handle.get(dbCheckEntity.getCheckFiele()),dbCheckEntity.getTargetResult()));
                    Log.info("---【用例断言】:数据库数据包含断言通过");
                }else{
                    Log.error("---【error】:数据库结果包含断言数组越界，请检查提取参数的下标数据, CaseNum:"+apiAutoTestEntity.getCaseNum()+";越界数据:"+apiAutoTestEntity.getCheckPoint()+";");
                }
            });
        }
        apiAutoTestEntity.setAssertResult(result.get());
        return apiAutoTestEntity;
    }
}
